﻿using System;
using System.Collections.Generic;
using System.Linq;
using Amazon;
using Amazon.ElasticLoadBalancing;
using Amazon.ElasticLoadBalancing.Model;
using System.Web;
using System.Net;
using System.Text.RegularExpressions;

namespace Web_App___AWS_ELB_Monitor
{
    public static class ELBDataHelper
    {
        private const string ELB_EU_ServiceUrl = "https://eu-west-1.elasticloadbalancing.amazonaws.com";

        public static AmazonElasticLoadBalancing GetELBClient()
        {
            return AWSClientFactory.CreateAmazonElasticLoadBalancingClient(CustomValueHelper.GetProperty("AWSAccessKey"),
                                                                               CustomValueHelper.GetProperty("AWSSecretKey"),
                                                                               new AmazonElasticLoadBalancingConfig { ServiceURL = ELB_EU_ServiceUrl });

        }

        public static IEnumerable<LoadBalancerDescription> GetAllLoadBalancers()
        {
            AmazonElasticLoadBalancing lbClient = GetELBClient();
            DescribeLoadBalancersResponse lbList = lbClient.DescribeLoadBalancers(new DescribeLoadBalancersRequest());
            return lbList.DescribeLoadBalancersResult != null
                       ? lbList.DescribeLoadBalancersResult.LoadBalancerDescriptions
                       : new List<LoadBalancerDescription>();
        }

        public static LoadBalancerDescription GetLoadBalancer(string loadBalancerName)
        {
            var result = GetELBClient().DescribeLoadBalancers(new DescribeLoadBalancersRequest().WithLoadBalancerNames(loadBalancerName));
            if (result.DescribeLoadBalancersResult == null)
            {
                throw new Exception("Load Balancer request did not result in a valid response for loadbalancer with name: " + loadBalancerName);
            }
            return result.DescribeLoadBalancersResult.LoadBalancerDescriptions.FirstOrDefault();
        }

        public static IList<InstanceState> GetInstanceHealthStatuses(string loadbalancerName)
        {
            return GetELBClient().DescribeInstanceHealth(new DescribeInstanceHealthRequest().WithLoadBalancerName(loadbalancerName)).DescribeInstanceHealthResult.InstanceStates;
        }

        public static int GetELBPreviewPort(string elbHealthCheck)
        {
            Regex numberFinder = new Regex(@"\d+");
            var match = numberFinder.Match(elbHealthCheck);
            if (match.Success) return int.Parse(match.Value);
            return 80;
        }

        public static string GetELBPreviewUrl(string instanceDNS, string elbHealthCheck, string path)
        {
            string root = elbHealthCheck.ToLower().Replace("http", instanceDNS);
            var slashPos = root.IndexOf("/");
            if (slashPos >= 0)
            {
                root = root.Substring(0, slashPos);
            }

            string rootUrl = String.Concat("http://", root);

            if (!String.IsNullOrWhiteSpace(path))
            {
                rootUrl += String.Concat("/", path);
            }

            return rootUrl;
        }

        public static HttpWebResponse GetELBPreviewWebResponse(string instanceDNS, string elbHealthCheck, string path)
        {
            HttpWebResponse response = null;
            try
            {
                string url = GetELBPreviewUrl(instanceDNS, elbHealthCheck, path);

                var request = WebRequest.Create(url);
                // Get the response.
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                if (ex.Response == null || ex.Status != WebExceptionStatus.ProtocolError)
                    return null;

                return (HttpWebResponse)ex.Response;
            }
            catch
            {
                return null;
            }

            return response;
        }


        public static string GetUrlForELB(string elbName)
        {
            //TODO: implement translation service
            return null;
        }
    }
}